#pragma once 

#include "parameter/Parameter.h"
#include "base/WrapperVtkmTypes.h"
#include "mesh/GeneratedMesh.h"
#include "base/EulerSystem.h"
#include "base/IsoVortexProblem.h"
#include "output/OutputContainer.h"

#include <string>
#include <memory>

class Mesh;
class SystemBase;

class Application
{
public:
	static Parameter validParams()
	{
		Parameter params;
		return params;
	}

	~Application() = default;

	Application() = default;
	Application(Parameter params)
	{
	}

	void Run()
	{
		for (_cur_time_step = 0; _cur_time_step < _tot_time_steps; _cur_time_step++)
		{
			_sys->Update();
			_outputs.Execute();
		}
	}

	void CreateMesh(const Parameter& param)
	{
		Id3 dim = { 100,100,100 };
		this->_mesh = std::make_shared<GeneratedMesh>(dim, Id3{ -10,-10,-1 }, Id3{ 10,10,1 });
		_mesh->Build();
	}

	void CreateSystem(const Parameter& param)
	{
		_sys = std::make_shared<IsoVortexProblem>(*_mesh);
	}

	void InitSystem()
	{
		_sys->Projection();
	}

	const std::shared_ptr<SystemBase> GetSystem() const { return this->_sys; }
		
	OutputContainer& GetOutputContainer() { return this->_outputs; }

	const Id& CurrentTimeStep() const { return this->_cur_time_step; }
	const Id& ToTalTimeSteps() const {return this->_tot_time_steps;	}

	void SetInputFile(std::string file)
	{
		this->_input_file = file;
	}

	void SetupAction()
	{

	}

private:
	std::string name;
	Parameter _param;
	std::string _input_file;

	std::shared_ptr<SystemBase> _sys;
	std::shared_ptr<Mesh> _mesh;

	Id _tot_time_steps = 10000;
	Id _cur_time_step = 0;

	OutputContainer _outputs;
};
